package org.ddd.productdemo.domaindriven.domain.model.aggregate;

import org.ddd.productdemo.domaindriven.domain.model.entity.CustomerId;
import org.ddd.productdemo.domaindriven.domain.model.entity.OrderLine;
import org.ddd.productdemo.domaindriven.domain.model.entity.Product;
import org.ddd.productdemo.domaindriven.domain.model.valueobject.Money;
import org.ddd.productdemo.domaindriven.domain.model.valueobject.OrderStatus;

import java.util.ArrayList;
import java.util.List;

public class Order {

    private OrderId id;
    private CustomerId customerId;
    private List<OrderLine> orderLines = new ArrayList<>();
    private OrderStatus status;
    private Money totalAmount;

    public Order(CustomerId customerId) {
        this.customerId = customerId;
    }

    public OrderId getId() {
        return id;
    }

    public void setId(OrderId id) {
        this.id = id;
    }

    public CustomerId getCustomerId() {
        return customerId;
    }

    public void setCustomerId(CustomerId customerId) {
        this.customerId = customerId;
    }

    public List<OrderLine> getOrderLines() {
        return orderLines;
    }

    public void setOrderLines(List<OrderLine> orderLines) {
        this.orderLines = orderLines;
    }

    public OrderStatus getStatus() {
        return status;
    }

    public void setStatus(OrderStatus status) {
        this.status = status;
    }

    public Money getTotalAmount() {
        return totalAmount;
    }

    public void setTotalAmount(Money totalAmount) {
        this.totalAmount = totalAmount;
    }

    // 领域行为
    public void addProduct(Product product, int quantity) {
        if (!product.isAvailable() || product.getStock() < quantity) {
            throw new IllegalArgumentException("Product not available");
        }

        OrderLine orderLine = new OrderLine(product.getId(), product.getPrice(), quantity);
        orderLines.add(orderLine);
        recalculateTotal();
    }

    public void confirm() {
        if (orderLines.isEmpty()) {
            throw new IllegalStateException("Cannot confirm empty order");
        }
        this.status = OrderStatus.CONFIRMED;
    }

    private void recalculateTotal() {
        this.totalAmount = orderLines.stream()
                .map(OrderLine::getSubtotal)
                .reduce(Money.ZERO, Money::add);
    }

}
